<template>
    <div style="width: 100%; height: 100%; overflow: hidden">
      <div ref="container" class="scroll-container">
        <div ref="content">
          <slot></slot>
        </div>
      </div>
    </div>
  </template>
    
    <script lang="ts" setup>
  import { ref, onMounted, onBeforeUnmount } from "vue";
  /**
   * speed:滚动速度 或者 每次跳动滚动的时间                     :Number
   * direction:移动方向，'up','down','left','right'                   :String
   * beat:是否为跳动展示 若为true时，speed默认时时间间隔，默认为false   :Boolean
   */
  
  let props = withDefaults(
    defineProps<{
      speed?: number;
      direction?: string;
      beat?: boolean;
    }>(),
    {
      direction: "up",
      beat: false,
      speed: 1,
    }
  );
  
  const container = ref<HTMLDivElement | null>(null);
  const content = ref<HTMLDivElement | null>(null);
  const firstChild = ref<any>(); //元素下面的第一个子级
  const rect = ref<any>(); //子级的完整信息
  const height = ref<number>(0); //单个子级的高度
  const width = ref<number>(0); //单个子级的宽度
  const childCount = ref<number>(0); //子级的数量
  let num = 0; //滚动的距离
  let animationFrame: any = null; //滚动实例
  
  function scroll() {
    if (props.beat) {
    } else {
      switch (props.direction) {
        case "up":
          requestAnimationFrame(moveUp);
          break;
        case "down":
          requestAnimationFrame(moveDown);
          break;
        case "left":
          requestAnimationFrame(moveLeft);
          break;
        case "right":
          requestAnimationFrame(moveRight);
          break;
        default:
          break;
      }
    }
  }
  function moveUp() {
    num += Number(props.speed);
    if (num > Number(height.value * childCount.value) / 2) {
      num = 0;
    }
    if (container.value) {
      container.value.style.transform = `translateY(-${num}px)`;
      animationFrame = requestAnimationFrame(moveUp);
    }
  }
  function moveDown() {
    console.log(num);
    num += Number(props.speed);
    if (num > 0) {
      num = -Number(height.value * childCount.value) / 2;
    }
  
    if (container.value) {
      container.value.style.transform = `translateY(${num}px)`;
      animationFrame = requestAnimationFrame(moveDown);
    }
  }
  function moveLeft() {
    num += Number(props.speed);
    if (num > Number(width.value * childCount.value) / 2) {
      num = 0;
    }
    if (container.value) {
      container.value.style.transform = `translateX(-${num}px)`;
      animationFrame = requestAnimationFrame(moveLeft);
    }
  }
  function moveRight() {
    num += Number(props.speed);
    if (num > 0) {
      num = -Number(width.value * childCount.value) / 2;
    }
    if (container.value) {
      container.value.style.transform = `translateX(${num}px)`;
      animationFrame = requestAnimationFrame(moveRight);
    }
  }
  //开始滚动
  function start() {
    scroll();
  }
  //停止滚动
  function stop() {
    if (animationFrame) {
      cancelAnimationFrame(animationFrame);
      animationFrame = null;
    }
  }
  
  function init() {
    if (content.value) {
      // 将内容复制一份，以实现无缝滚动
      content.value.innerHTML += content.value.innerHTML;
      if (props.direction === "left" || props.direction === "right") {
        Array.from(content.value.children).forEach((child: any) => {
          child.style.display = "inline-block";
        });
      }
  
      //获取子级的各类信息
      firstChild.value = content.value.firstElementChild;
      rect.value = firstChild.value.getBoundingClientRect();
      height.value = rect.value.height || 0;
      width.value = rect.value.width || 0;
      childCount.value = content.value.childElementCount || 0;
  
      //鼠标移入 暂停
      content.value.addEventListener("mouseenter", () => {
        stop();
      });
      //鼠标移入 开始
      content.value.addEventListener("mouseleave", () => {
        start();
      });
      start();
    }
  }
  
  onMounted(() => {
    init();
  });
  //销毁时停止滚动
  onBeforeUnmount(() => {
    stop();
  });
  </script>
    
    <style scoped>
  .scroll-container {
    white-space: nowrap;
  }
  
  .scroll-container > div {
    display: inline-block;
  }
  </style>